home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
pascal
/
fielddh.exe
/
DATES.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1992-03-24
|
25KB
|
682 lines
{$F+,O+}
UNIT Dates;
{ Version 1R0 - 1991 03 25 }
{ 1R1 - 1991 04 09 - corrected several bugs, and }
{ - deleted <JulianDa2>, <Da2OfWeek> and }
{ <JulianDa2ToDate> - all found to be not }
{ completely reliable. }
INTERFACE
{ These routines all assume that the year (y, y1) value is supplied in a }
{ form that includes the century (i.e., in YYYY form). No checking is }
{ performed to ensure that a month (m, m1) value is in the range 1..12 }
{ or that a day (d, d1) value is in the range 1..28,29,30,31. The }
{ FUNCTION ValidDate may be used to check for valid month and day }
{ parameters. FUNCTION DayOfYearToDate returns month and day (m, d) both }
{ = 0 if the day-of-the-year (nd) is > 366 for a leap-year or > 365 for }
{ other years. }
{ NOTE: As written, FUNCTION Secs100 requires the presence of a 80x87 }
{ co-processor. Its declaration and implementation may be altered to }
{ REAL to make use of the floating-point emulation. }
{ Because the Gregorian calendar was not implemented in all countries at }
{ the same time, these routines are not guaranteed to be valid for all }
{ dates. The real utility of these routines is that they will not fail }
{ on December 31, 1999 - as will many algorithms used in MIS programs }
{ implemented on mainframes. }
{ The routines are NOT highly optimized - I have tried to maintain the }
{ style of the algorithms presented in the sources I indicate. Any }
{ suggestions for algorithmic or code improvements will be gratefully }
{ accepted. This implementation is in the public domain - no copyright }
{ is claimed. No warranty either express or implied is given as to the }
{ correctness of the algorithms or their implementation. }
{ Author: Charles B. Chapman, London, Ontario, Canada [74370,516] }
{ Thanks to Leonard Erickson who supplied a test suite of values. }
FUNCTION IsLeap (y : WORD) : BOOLEAN;
FUNCTION ValidDate (y, m, d : WORD) : BOOLEAN;
FUNCTION ValidDate_Str (Str : string; {DWH}
VAR Y, M, D : word;
VAR Err_Str : string) : boolean;
FUNCTION ValidTime_Str (Str : string; {DWH}
VAR H, M, S : word;
VAR Err_Str : string) : boolean;
FUNCTION DayOfYear (y, m, d : WORD) : WORD;
FUNCTION JulianDay (y, m, d : WORD) : LONGINT;
FUNCTION JJ_JulianDay (y, m, d : word) : LONGINT; {DWH}
FUNCTION DayOfWeek (y, m, d : WORD) : WORD;
FUNCTION DayOfWeek_Str (y, m, d : WORD) : String; {DWH}
FUNCTION TimeStr (h, m, s, c : WORD) : STRING;
FUNCTION TimeStr2 (h, m, s : WORD) : STRING;
FUNCTION SIDateStr (y, m, d : WORD; SLen : BYTE; FillCh : CHAR) : STRING;
FUNCTION MDYR_Str (y, m, d : WORD): STRING; {DWH}
FUNCTION Secs100 (h, m, s, c : WORD) : DOUBLE;
PROCEDURE DayOfYearToDate (nd, y : WORD; VAR m, d : WORD);
PROCEDURE JulianDayToDate (nd : LONGINT; VAR y, m, d : WORD);
PROCEDURE JJ_JulianDayToDate (nd : LONGINT; VAR y, m, d : WORD); {DWH}
PROCEDURE DateOfEaster (Yr : WORD; VAR Mo, Da : WORD);
PROCEDURE AddDays (y, m, d : WORD; plus : LONGINT; VAR y1, m1, d1 : WORD);
FUNCTION Lotus_Date_Str (nd : LONGINT) : string; {DWH}
{==========================================================================}
IMPLEMENTATION
USES
Dos;
{==========================================================================}
FUNCTION IsLeap (y : WORD) : BOOLEAN;
{ Returns TRUE if <y> is a leap-year }
BEGIN
IF y MOD 4 <> 0 THEN
IsLeap := FALSE
ELSE
IF y MOD 100 = 0 THEN
IF y MOD 400 = 0 THEN
IsLeap := TRUE
ELSE
IsLeap := FALSE
ELSE
IsLeap := TRUE
END; { IsLeap }
{==========================================================================}
FUNCTION DayOfYear (y, m, d : WORD) : WORD;
{ function IDAY from remark on CACM Algorithm 398 }
{ Computes day of the year for a given calendar date }
{ GIVEN: y - year }
{ m - month }
{ d - day }
{ RETURNS: day-of-the-year (1..366, given valid input) }
VAR
yy, mm, dd, Tmp1 : LONGINT;
BEGIN
yy := y;
mm := m;
dd := d;
Tmp1 := (mm + 10) DIV 13;
DayOfYear := 3055 * (mm + 2) DIV 100 - Tmp1 * 2 - 91 +
(1 - (yy - yy DIV 4 * 4 + 3) DIV 4 +
(yy - yy DIV 100 * 100 + 99) DIV 100 -
(yy - yy DIV 400 * 400 + 399) DIV 400) * Tmp1 + dd
END; { DayOfYear }
{==========================================================================}
FUNCTION JulianDay (y, m, d : WORD) : LONGINT;
{ procedure JDAY from CACM Alorithm 199 }
{ Computes Julian day number for any Gregorian Calendar date }
{ GIVEN: y - year }
{ m - month }
{ d - day }
{ RETURNS: Julian day number (astronomically, for the day }
{ beginning at noon) on the given date. }
VAR
Tmp1, Tmp2, Tmp3, Tmp4, Tmp5 : LONGINT;
BEGIN
IF m > 2 THEN
BEGIN
Tmp1 := m - 3;
Tmp2 := y
END
ELSE
BEGIN
Tmp1 := m + 9;
Tmp2 := y - 1
END;
Tmp3 := Tmp2 DIV 100;
Tmp4 := Tmp2 MOD 100;
Tmp5 := d;
JulianDay := (146097 * Tmp3) DIV 4 + (1461 * Tmp4) DIV 4 +
(153 * Tmp1 + 2) DIV 5 + Tmp5 + 1721119
END; { JulianDay }
{==========================================================================}
PROCEDURE DayOfYearToDate (nd, y : WORD; VAR m, d : WORD);
{ procedure CALENDAR from CACM Algorithm 398 }
{ Computes month and day from given year and day of the year }
{ GIVEN: nd - day-of-the-year (1..366) }
{ y - year }
{ RETURNS: m - month }
{ d - day }
VAR
Tmp1, Tmp2, Tmp3, Tmp4, DaYr : LONGINT;
BEGIN
DaYr := nd;
IF (DaYr = 366) AND (DayOfYear (y, 12, 31) <> 366) THEN
DaYr := 999;
IF DaYr <= 366 THEN
BEGIN
IF y MOD 4 = 0 THEN
Tmp1 := 1
ELSE
Tmp1 := 0;
IF (y MOD 400 = 0) OR (y MOD 100 <> 0) THEN
Tmp2 := Tmp1
ELSE
Tmp2 := 0;
Tmp1 := 0;
IF DaYr > Tmp2 + 59 THEN
Tmp1 := 2 - Tmp2;
Tmp3 := DaYr + Tmp1;
Tmp4 := ((Tmp3 + 91) * 100) DIV 3055;
d := ((Tmp3 + 91) - (Tmp4 * 3055) DIV 100);
m := (Tmp4 - 2)
END
ELSE
BEGIN
d := 0;
m := 0
END
END; { DayOfYearToDate }
{==========================================================================}
PROCEDURE JulianDayToDate (nd : LONGINT; VAR y, m, d : WORD);
{ procedure JDATE from CACM Algorithm 199 }
{ Computes calendar date from a given Julian day number for an